package com.flyqiu.form.extensions.convert.mapping;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.flyqiu.common.sc.FlyQiuSCContext;
import com.flyqiu.common.sc.FlyQiySCManage;
import com.flyqiu.common.sc.calculate.FlyQiuCalculate;
import com.flyqiu.common.sc.statistical.FlyQiuPropertyStatistical;
import com.flyqiu.common.tools.FlyQiuCollectionTools;
import com.flyqiu.form.extensions.FlyQiuFormDataConvert;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态表单映射器，用于处理具有动态子项的表单数据转换
 * 继承自AvueDefaultMapper，实现了对动态表单数据的特殊处理，特别是对子项的汇总统计功能
 */
@Slf4j
public class AvueDynamicMapper extends AvueDefaultMapper {
    public static final String MAPPER_TYPE = "dynamic";
    private static final String CHILDREN_KEY = "children";

    private FlyQiuFormDataConvert formMapperConvert;

    private List<FlyQiuPropertyStatistical<JSONObject>> columnSummaries;
    private FlyQiySCManage flyQiySCManage;

    /**
     * 初始化映射器，包括克隆表单转换器和初始化子项的汇总统计
     *
     * @param convert 表单数据转换器实例
     * @param column  表示表单字段的JSON对象，可能包含子项
     */
    @Override
    public void init(FlyQiuFormDataConvert convert, JSONObject column) {
        super.init(convert, column);
        formMapperConvert = FlyQiuFormDataConvert.clone(convert);
        if (!column.containsKey(CHILDREN_KEY)) {
            return;
        }

        JSONObject childrenForm = column.getJSONObject(CHILDREN_KEY);
        this.flyQiySCManage = convert.getFlyQiySCManage();
        columnSummaries = initSummaryColumn(childrenForm);
    }

    /**
     * 根据子表单配置初始化汇总统计列
     *
     * @param childrenForm 子表单的JSON对象，包含是否显示汇总及汇总列的配置
     * @return 初始化后的汇总统计列列表，如果不存在或无需汇总则返回null
     */
    public List<FlyQiuPropertyStatistical<JSONObject>> initSummaryColumn(JSONObject childrenForm) {

        if (!childrenForm.containsKey("showSummary")) {
            return null;
        }
        boolean showSummary = childrenForm.getBooleanValue("showSummary");
        if (!showSummary) {
            return null;
        }
        JSONArray jsonArray = childrenForm.getJSONArray("sumColumnList");
        if (FlyQiuCollectionTools.isEmpty(jsonArray)) {
            return null;
        }
        JSONObject jsonObject;
        List<FlyQiuPropertyStatistical<JSONObject>> result = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            jsonObject = jsonArray.getJSONObject(i);
            String calculateType = jsonObject.getString("calculateType");
            String fieldName = jsonObject.getString("fieldName");
            String prefix = jsonObject.getString("prefix");
            String suffix = jsonObject.getString("suffix");
            Integer precision = jsonObject.getInteger("precision");
            if (precision == null) {
                precision = 0;
            }
            FlyQiuCalculate<?> calculate = flyQiySCManage.createCalculate(calculateType);
            String split = jsonObject.getString("split");
            FlyQiuPropertyStatistical<JSONObject> statistical = new FlyQiuPropertyStatistical<JSONObject>(fieldName, calculate);
            statistical.setPrefix(prefix);
            statistical.setSuffix(suffix);
            statistical.setSplit(split);
            statistical.setPrecision(precision);
            result.add(statistical);
        }

        return result;
    }

    /**
     * 将标签转换为对应的值，目前直接调用父类方法实现
     *
     * @param label 需要转换的标签字符串
     * @return 转换后的值
     */
    @Override
    public Object labelToValue(String label) {
        return super.labelToValue(label);
    }

    /**
     * 将值转换为对应的标签，并对子项数据进行汇总统计
     *
     * @param value 需要转换的值，可以是表示数据的JSONArray
     * @return 转换并汇总统计后的数据，以JSONArray形式返回
     */
    @Override
    public Object valueToLabel(Object value) {
        if (value == null) {
            return super.valueToLabel(value);
        }
        JSONArray jsonArray = objectToJSONArray(value);
        if (jsonArray == null) return super.valueToLabel(value);
        JSONArray array = formMapperConvert.convertDataToLabel(jsonArray);
        if (array == null) return super.valueToLabel(value);
        FlyQiuSCContext<JSONObject> context = flyQiySCManage.createContext(array);

        JSONObject statistical = flyQiySCManage.statistical(context, columnSummaries);
        if (statistical != null && !statistical.isEmpty()) {
            array.add(statistical);
        }
        return array;
    }
}
